package com.ww.springboot.boot.thread.study.base.lock.aqs;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 公平性锁每次都是从同步队列中的第一个节点获取到锁，而非公平性锁出现了一个线程连续获取锁的情况。
 * 为什么会出现线程连续获取锁的情况呢？
 * 回顾nonfairTryAcquire(int acquires)方法，当一个线程请求锁时，只要获取了同步状态即成功获取锁。
 * 在这个前提下，刚释放锁的线程再次获取同步状态的几率会非常大，使得其他线程只能在同步队列中等待。
 *
 * 因为其他的都在排队自旋中 当前线程可以直接去获取锁
 */
public class FairAndUnfairTest {
    private static Lock fairLock        = new ReentrantLock2(true);
    private static Lock    unfairLock    = new ReentrantLock2(false);
    @Test
    public void fair() {
            testLock(fairLock);
    }
    @Test
    public void unfair() {
            testLock(unfairLock);
    }
    private void testLock(Lock lock) {
            // 启动5个Job（略）
    }
    private static class Job extends Thread {
            private Lock    lock;
            public Job(Lock lock) {
                    this.lock = lock;
            }
            public void run() {
                    // 连续2次打印当前的Thread和等待队列中的Thread（略）
            }
    }
    private static class ReentrantLock2 extends ReentrantLock {
            public ReentrantLock2(boolean fair) {
                    super(fair);
            }
            public Collection<Thread> getQueuedThreads() {
                    List<Thread> arrayList = new ArrayList<Thread>(super.
                    getQueuedThreads());
                    Collections.reverse(arrayList);
                    return arrayList;
            }
    }
}